/******************************************************************************
 * Copyright (c) 2008, Intalio Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     Intalio Inc. - initial API and implementation
 *******************************************************************************
 *
 * Date         Author             Changes
 * Apr 25, 2008      Antoine Toulme     Created
 */
package ms.unicorn.diagram.borders;

import ms.unicorn.diagram.edit.parts.IFigureEditPart;
import ms.unicorn.diagram.figures.SlidableAnchorEx;
import ms.unicorn.dsl.IBorderEx;
import ms.unicorn.dsl.IFigureEx;
import ms.unicorn.dsl.ITheme;

import org.eclipse.draw2d.AbstractBorder;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.ConnectionAnchor;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.RoundedRectangleAnchor;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.PrecisionPoint;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gmf.runtime.gef.ui.figures.SlidableAnchor;

/**
 * Scheme border for rounded rectangle shapes.
 *
 *
 * @author <a href="http://www.intalio.com">Intalio Inc.</a>
 * @author <a href="mailto:atoulme@intalio.com">Antoine Toulme</a>
 */
public class RoundedSchemeBorder extends AbstractBorder implements IBorderEx {
    
	public static final RoundedSchemeBorder INSTANCE = new RoundedSchemeBorder();
	
    public static final Insets INSETS = new Insets(0, 0, 0, 0);	

	@Override
	public void paint(IFigure figure, Graphics graphics, Insets insets, ITheme theme) {
		graphics.pushState();
		try {
			if (theme.isShadow())    
		        fillShadow(figure, graphics, insets, theme);        
	        graphics.setForegroundColor(theme.getBackgroundColor());
	        
	        graphics.setBackgroundColor(ColorConstants.white);
	        graphics.setAlpha(theme.getBackgroundAlpha());
	        graphics.setLineWidthFloat(theme.getLineWidth());
	        graphics.setLineStyle(theme.getLineStyle());
	                        
	        Rectangle rt = getAdjustedBound(figure, theme);
	        if (theme.isShadow()) 
	        	rt.resize(-4, -4);
	        graphics.fillRoundRectangle(rt, theme.getRoundCorner(), theme.getRoundCorner());
	        
	        graphics.fillGradient(rt, true);
	        graphics.setForegroundColor(theme.getForeColor());
	        graphics.drawRoundRectangle(rt, theme.getRoundCorner(), theme.getRoundCorner());
		}
		finally {
			graphics.popState();
		}
	}
	
	public Rectangle getAdjustedBound(IFigure figure, ITheme theme) {
		Rectangle rt = figure.getBounds().getCopy();
        rt.resize(-1*theme.getLineWidth(), -1*theme.getLineWidth());
        rt.translate(0.5*theme.getLineWidth(), 0.5*theme.getLineWidth());
        return rt;
	}
            
    public void paint(IFigure fig, Graphics graphics, Insets insets) {
        return;
    }
    
    protected void fillShadow(IFigure fig, Graphics graphics, Insets insets, ITheme theme) {
        Rectangle rect = null;
        graphics.setAlpha(theme.getShadowAlpha());
        graphics.setBackgroundColor(theme.getShadowColor());
        
        rect = fig.getBounds().getCopy().translate(3, 3)
                .resize(-4, -4);//getPaintRectangle(fig, insets);
        
        graphics.fillRoundRectangle(rect, theme.getRoundCorner(), theme.getRoundCorner());
    }
    
    public Insets getInsets(IFigure figure, ITheme theme) {
    	int r = theme.getRoundCorner()/4;
    	int w = (int)theme.getLineWidth()/2;
    	return new Insets(r, w, r, w);
    }

	@Override
	public Class<? extends ConnectionAnchor> getConnectionAnchorClass() {
		return SlidableAnchorEx.class;
	}

	@Override
	public double getSlidableAnchorArea() {
		return 0.5;
	}

	@Override
	public PointList getPolyPoints(IFigure figure) {
		return null;
	}

	@Override
	public Insets getInsets(IFigure figure) {
		return INSETS;
	}

	@Override
	public ConnectionAnchor createAnchor(IFigure figure) {
		int corner = 5;
		if (figure instanceof IFigureEx) {
			corner = ((IFigureEx) figure).getTheme().getRoundCorner();
		}
		//return new RoundedRectangleAnchor((Figure) figure, new Dimension(corner, corner));
		return new SlidableAnchorEx(figure);
	}

	@Override
	public ConnectionAnchor createAnchor(IFigure figure, PrecisionPoint p) {
		//return createAnchor(figure);
		return new SlidableAnchorEx(figure, p);
	}
}
